package web.common.internal.core.security;

import web.common.core.security.Digest;
import web.common.core.security.DigestType;
import web.common.core.security.PasswordEncoder;
import web.common.core.security.PasswordEncoderType;
import web.common.core.util.RandomUtil;

/**
 * @author Jin Zheng
 * @since 2022-01-19
 */
public class DigestPasswordEncoder implements PasswordEncoder {
	private static final String HASH_TPL = "{%s}%s";
	private static final String ENCODED_TPL = "{%s}%s$%s";
	private final PasswordEncoderType type;
	private final Digest digest;
	private final int randomLength;

	public DigestPasswordEncoder(PasswordEncoderType type, int randomLength) {
		this.type = type;
		this.digest = new DefaultDigest(DigestType.getType(type.name()));
		this.randomLength = randomLength;
	}

	@Override
	public String encode(String origin) {
		String random = RandomUtil.rand(RandomUtil.RandomType.UPPER_LOWER_CASE_NUMBER, randomLength);
		String raw = String.format(HASH_TPL, random, origin);
		String hash = digest.digestToBase64(raw);
		return String.format(ENCODED_TPL, type, random, hash);
	}

	@Override
	public boolean matches(String origin, String encoded) {
		var info = PasswordEncoderFacade.parseInfo(encoded);
		if (info.getType() != this.type) {
			throw new UnsupportedOperationException("错误类型: " + info.getType());
		}
		String raw = String.format(HASH_TPL, info.getRandom(), origin);
		String hash = digest.digestToBase64(raw);
		return info.getEncoded().equals(hash);
	}
}
